home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
lang_c
/
cug167
/
spline.doc
< prev
Wrap
Text File
|
1985-08-21
|
11KB
|
304 lines
/*
HEADER: CUG
TITLE: Cubic Spline Functions Theory
VERSION: 1.00
DATE: 11/01/85
DESCRIPTION: "Mathematical background and development of
equations used in SPLINE, a full emulation of
Unix's 'spline' utility."
KEYWORDS: spline, graphics, plot, filter, UNIX
SYSTEM:
FILENAME: SPLINE.DOC
WARNINGS:
CRC: xxxx
SEE-ALSO: SPLINE.C
AUTHORS: Ian Ashdown - byHeart Software
COMPILERS:
REFERENCES: AUTHORS: R.W. Hamming
TITLE: Numerical Methods for Scientists and
Engineers, 2nd Edition
pp. 349 - 355, McGraw-Hill (1973)
AUTHORS: Forsythe, Malcolm & Moler
TITLE: Computer Methods for Mathematical
Computations
pp. 70 - 83, Prentice-Hall
ENDREF
*/
/*-------------------------------------------------------------*/
byHeart Software
1089 West 21st Street
North Vancouver, B.C. V6J 1G8
Canada
November 1st, 1985
Cubic Spline Functions Theory
-----------------------------
Ian E. Ashdown
byHeart Software
References: 1. Numerical Methods for Scientists and Engineers
R.W. Hamming, 2nd Edition
pp.349 - 355, McGraw-Hill (1973)
2. Computer Methods for Mathematical Computations
Forsythe, Malcolm & Moler
pp. 70 - 83, Prentice-Hall
Cubic spline functions are a mathematical abstraction of a
draftsman's mechanical splines. Given a set of abscissae and
ordinates, the draftsman first plots this data on a sheet of
paper, then uses a spline - a flexible strip of wood or plastic -
to draw a smooth curve between them. The spline is held in place
at the given points (historically called "knots") with weights.
If the spline is not too severely stressed, elementary beam
theory shows that it will conform to a curve described by a cubic
polynomial equation between each pair of knots, and that adjacent
polynomials will join continuously with continuous first and
second derivatives. The result is a visually "smooth" curve. The
following discussion develops the mathematics necessary to model
these splines with a computer.
Given a set of datum, stated as abscissae x[i] (i = 1,...,n)
and corresponding ordinates y[i], let y(x) be an interpolated
curve through this data, defined as the composite function
y(x) = f[i](x) for x[i] <= x < x[i+1], i = 1,...,n-2 (1)
and x[n-1] <= x <= x[n]
where each function f[i](x) is a cubic polynomial of the form
f[i](x) = a * pow(x,3) + b * pow(x,2) + c * x + d (2)
(a,b,c and d are constants, and "pow(x,y)" means "x" to
the power of "y")
In other words, f[](x) is a set of functions, each of which
is defined only over the specific interval between two adjacent
abscissae. (This is equivalent to describing the spline between
each pair of adjacent knots using a cubic polynomial equation, as
per elementary beam theory.) The concatenation of these functions
over the given range of abscissae defines the function y(x).
Furthermore, let's define y'[i] and y"[i] as the first and
second derivatives of y(x) at x = x[i]. Continuous first and
second derivatives at the knots of the spline then imply the
following continuity conditions:
f[i](x[i]) = y[i] i = 1,...,n-1 (3)
f[i-1](x[i]) = y[i] i = 2,...,n (4)
f'[i-1](x[i]) = f'[i](x[i]) i = 2,...,n-1 (5)
f"[i-1](x[i]) = f"[i](x[i]) i = 2,...,n-1 (6)
These conditions state that the functions f[i](x) are
continuous where they join at their endpoints (the ordinates
y[i]), thus ensuring the "smoothness" of the composite curve
y(x).
Since each function f[i](x) is a cubic polynomial, it follows
that its third derivative is a constant. This means that y"(x) is
a linear function over each interval. Thus, defining
h[i] = x[i+1] - x[i] (7)
linear interpolation gives the equation
f"[i](x) = (y"[i] * (x[i-1] - x) + (8)
y"[i+1] * (x - x[i]))/h[i]
Integrating this equation twice and selecting the constants
of integration such that Equations (3) and (4) are satisfied
gives:
f[i](x) = (y[i] * (x[i+1] - x) + (9)
y[i+1] * (x - x[i]))/h[i] -
(pow(h[i],2)/6 *
(y"[i] * ((x[i+1] - x)/
h[i] -(pow((x[i+1] - x)/h[i],3)) -
y"[i+1] * ((x - x[i])/h[i] -
pow((x - x[i])/h[i],3)))
Note that the first two terms are a linear interpolation
function between ordinates y[i] and y[i+1]. The remainder of the
equation is the cubic "correction factor".
Differentiating Equation (9) and evaluating yields:
f'[i](x[i]) = (y[i+1] - y[i])/h[i] - h[i] * (10)
(2 * y"[i] + y"[i+1])/6
f'[i-1](x[i]) = (y[i] - y[i-1])/h[i-1] + h[i-1] * (11)
(y"[i-1] + 2 * y"[i])/6
Using the identity shown in Equation (5), we get:
h[i-1] * y"[i-1] + 2 * (h[i-1] + (12)
h[i]) * y"[i] + h[i] * y"[i+1] =
6 * ((y[i+1] - y[i])/h[i] - (y[i] - y[i-1])/h[i-1])
for i = 2,...,n-1
which must be satisfied at n-2 points by the n unknown quantities
y"[i]. In matrix form (using n = 6 as an example), we have:
+- -++- -+ +- -+ (13)
| h[1] c[2] h[2] 0 0 0 || y"[1] | = 6 * | d[2] |
| 0 h[2] c[3] h[3] 0 0 || y"[2] | | d[3] |
| 0 0 h[3] c[4] h[4] 0 || y"[3] | | d[4] |
| 0 0 0 h[4] c[5] h[5] || y"[4] | | d[5] |
+- -+| y"[5] | +- -+
| y"[6] |
+- -+
where c[i] = 2 * (h[i-1] + h[i])
and d[i] = (y[i+1] - y[i])/h[i] - (y[i] - y[i-1])/h[i-1]
Note that if we limit the abscissae to being equally spaced,
Equation (12) becomes:
h * y"[i-1] + 4 * h * y"[i] + h * y"[i] = (14)
6 * (y[i+1] - 2 * y[i] - y[i-1])/h
for i = 2,...,n-1
and our example Equation (13) becomes:
+- -++- -+ +- -+ (15)
| 1 4 1 0 0 0 || y"[1] | = 6 * | d[2] |
| 0 1 4 1 0 0 || y"[2] | | d[3] |
| 0 0 1 4 1 0 || y"[3] | | d[4] |
| 0 0 0 1 4 1 || y"[4] | | d[5] |
+- -+| y"[5] | +- -+
| y"[6] |
+- -+
where d[i] = (y[i+1] - 2 * y[i] - y[i-1])/h
Two more conditions are required to obtain a unique solution.
These can be obtained by specifying one condition at each end of
the interpolated curve. Several variations are possible, with
two being examined here.
The first one is to specify that
y"[1] = k * y"[2] and y"[n-1] = k * y"[n] (16)
where k is a constant. Equation (13) then becomes:
+- -++- -+ +- -+ (17)
| -1 k 0 0 0 0 || y"[0] | = 6 * | 0 |
| h[1] c[2] h[2] 0 0 0 || y"[1] | | d[2] |
| 0 h[2] c[3] h[3] 0 0 || y"[2] | | d[3] |
| 0 0 h[3] c[4] h[4] 0 || y"[3] | | d[4] |
| 0 0 0 h[4] c[5] h[5] || y"[4] | | d[5] |
| 0 0 0 0 k -1 || y"[6] | | 0 |
+- -++- -+ +- -+
where c[i] = 2 * (h[i-1] + h[i])
d[i] = (y[i+1] - y[i])/h[i] - (y[i] - y[i-1])/h[i-1]
For the case of equidistant abscissae, this becomes (with a
bit of matrix manipulation):
+- -++- -+ +- -+ (18)
| 4-k 1 0 0 || y"[2] | = 6 * | d[2] |
| 1 4 1 0 || y"[3] | | d[3] |
| 0 1 4 1 || y"[4] | | d[4] |
| 0 0 1 4-k || y"[5] | | d[5] |
+- -++- -+ +- -+
where d[i] = (y[i+1] - 2 * y[i] - y[i-1])/(h * h)
If the value of k is zero, we have y"[1] = y"[n] = 0. This is
equivalent to a mechanical spline whose ends are not constrained
beyond the data endpoints, and is known as the "natural" cubic
spline. A nonzero value of k is equivalent to bending the ends of
the mechanical spline, and will affect all of the interior cubic
polynomial functions. In this sense, the cubic spline is a global
function; however, the effect of changing k on the interior
polynomials rapidly decreases as one moves away from the
endpoints (which is what one would expect from intuition).
The second variation is more interesting, and comes from the
need to interpolate data extracted from periodic phenomenon. A
good example of this is a closed curve such as an ellipse. If the
abscissae are expressed over 360 degrees, the curve can be
modeled by a cubic spline function. However, we need to somehow
specify that the endpoints of the curve must be continuous with
respect to each other.
The ordinates are constrained by the data given to be equal
(i.e. - y[1] = y[n]). We need to specify the end conditions such
that
y'[1] = y'[n] and y"[1] = y"[n] (19)
The second derivatives are easy - they can be expressed directly
in matrix form. However, to solve for the first derivative of
y(x) at the end points, we need an equation that relates it to
y(x) and its second derivative. Equations (10) and (11) satisfy
this requirement. Evaluating them for x[1] and x[n] respectively
produces:
f'[1](x[1]) = (y[2] - y[1])/h[1] - h[1] * (20)
(2 * y"[1] + y"[2])/6
f'[n-1](x[n]) = (y[n] - y[n-1])/h[n-1] + h[n-1] * (21)
(y"[n-1] + 2 * y"[n])/6
But y'[1] = y'[n], so that
6 * (y[2] - y[1])/h[1] - (y[n] - y[n-1])/h[n-1] = (22)
h[n-1] * (y"[n-1] + 2 * y"[n]) +
h[1] * (2 * y"[1] + y"[2])
Our example equation (13) thus becomes:
+- -++- -+ +- -+ (23)
| 1 0 0 0 0 -1 || y"[0] | = 6 * | 0 |
| h[1] c[2] h[2] 0 0 0 || y"[1] | | d[2] |
| 0 h[2] c[3] h[3] 0 0 || y"[2] | | d[3] |
| 0 0 h[3] c[4] h[4] 0 || y"[3] | | d[4] |
| 0 0 0 h[4] c[5] h[5] || y"[4] | | d[5] |
| 2a a 0 0 b 2b || y"[6] | | e |
+- -++- -+ +- -+
where c[i] = 2 * (h[i-1] + h[i])
d[i] = (y[i+1] - y[i])/h[i] - (y[i] - y[i-1])/h[i-1]
a = h[1]
b = h[n-1]
e = (y[2] - y[1])/h[1] - (y[n] - y[n-1])/h[n-1]
For equidistant abscissae, this becomes (again with some
matrix manipulation):
+- -++- -+ +- -+ (24)
| 4 1 0 0 1 || y"[2] | = 6 * | d[2] |
| 1 4 1 0 0 || y"[3] | | d[3] |
| 0 1 4 1 0 || y"[4] | | d[4] |
| 0 0 1 4 1 || y"[5] | | d[5] |
| 1 0 0 1 4 || y"[6] | | e |
+- -++- -+ +- -+
where d[i] = (y[i+1] - 2 * y[i] - y[i-1])/(h * h)
e = (y[2] - y[1] - y[n] + y[n-1])/(h * h)
Other end conditions are possible. Using Equations (10) and
(11), you can specify the slope of the splines outside of the
range of the data by specifying the first derivatives at y[1] and
y[n]. You can also specify a linear combination of first and
second derivatives at the end points. However, the above will
generally prove the most useful.
In closing, it's worth noting that the matrices presented
above are diagonally dominant band matrices. This means that the
equations they represent will always have a solution, and that
they can be solved by reduction to upper triangular form and
subsequent back substitution without the need for pivoting. A few
moments' thought will also show that the non-zero elements can be
stored in a few linear arrays, and the remainder ignored. This
means that simple dedicated algorithms can be written to solve
the matrices in linear rather than cubic time, and to do so with
a very efficient utilization of core memory.
2] -